{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Visualizing CNN + Summary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting data/train-images-idx3-ubyte.gz\n",
      "Extracting data/train-labels-idx1-ubyte.gz\n",
      "Extracting data/t10k-images-idx3-ubyte.gz\n",
      "Extracting data/t10k-labels-idx1-ubyte.gz\n",
      "Packages loaded.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import matplotlib.pyplot as plt\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "%matplotlib inline  \n",
    "mnist = input_data.read_data_sets('data/', one_hot=True)\n",
    "trainimg   = mnist.train.images\n",
    "trainlabel = mnist.train.labels\n",
    "testimg    = mnist.test.images\n",
    "testlabel  = mnist.test.labels\n",
    "print (\"Packages loaded.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Define Networks\n",
    "## tf.variable_scope(\"NAME\"):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Parameters\n",
    "learning_rate   = 0.001\n",
    "training_epochs = 5\n",
    "batch_size      = 100\n",
    "display_step    = 1\n",
    "\n",
    "# Network\n",
    "n_input  = 784\n",
    "n_output = 10\n",
    "with tf.variable_scope(\"CNN_WEIGHTS\"):\n",
    "    weights  = {\n",
    "        'wc1': tf.Variable(tf.random_normal([3, 3, 1, 64], stddev=0.1)),\n",
    "        'wc2': tf.Variable(tf.random_normal([3, 3, 64, 128], stddev=0.1)),\n",
    "        'wd1': tf.Variable(tf.random_normal([7*7*128, 1024], stddev=0.1)),\n",
    "        'wd2': tf.Variable(tf.random_normal([1024, n_output], stddev=0.1))\n",
    "    }\n",
    "with tf.variable_scope(\"CNN_BIASES\"):\n",
    "    biases   = {\n",
    "        'bc1': tf.Variable(tf.random_normal([64], stddev=0.1)),\n",
    "        'bc2': tf.Variable(tf.random_normal([128], stddev=0.1)),\n",
    "        'bd1': tf.Variable(tf.random_normal([1024], stddev=0.1)),\n",
    "        'bd2': tf.Variable(tf.random_normal([n_output], stddev=0.1))\n",
    "    }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Network ready\n"
     ]
    }
   ],
   "source": [
    "def conv_basic(_input, _w, _b, _keepratio):\n",
    "    # Input\n",
    "    with tf.variable_scope(\"INPUT_LAYER\"):\n",
    "        _input_r = tf.reshape(_input, shape=[-1, 28, 28, 1])\n",
    "    # Conv1\n",
    "    with tf.variable_scope(\"CNN_CONV_1\"):\n",
    "        _conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(_input_r, _w['wc1']\n",
    "                    , strides=[1, 1, 1, 1], padding='SAME'), _b['bc1']))\n",
    "    with tf.variable_scope(\"CNN_POOL_1\"):\n",
    "        _pool1 = tf.nn.max_pool(_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1]\n",
    "                                , padding='SAME')\n",
    "        _pool_dr1 = tf.nn.dropout(_pool1, _keepratio)\n",
    "    # Conv2\n",
    "    with tf.variable_scope(\"CNN_CONV_2\"):\n",
    "        _conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(_pool_dr1, _w['wc2']\n",
    "                    , strides=[1, 1, 1, 1], padding='SAME'), _b['bc2']))\n",
    "    with tf.variable_scope(\"CNN_POOL_2\"):\n",
    "        _pool2 = tf.nn.max_pool(_conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1]\n",
    "                                , padding='SAME')\n",
    "        _pool_dr2 = tf.nn.dropout(_pool2, _keepratio)\n",
    "    with tf.variable_scope(\"FC_1\"):\n",
    "        # Vectorize\n",
    "        _dense1 = tf.reshape(_pool_dr2, [-1, _w['wd1'].get_shape().as_list()[0]])\n",
    "        # Fc1\n",
    "        _fc1 = tf.nn.relu(tf.nn.bias_add(tf.matmul(_dense1, _w['wd1']), _b['bd1']))\n",
    "        _fc_dr1 = tf.nn.dropout(_fc1, _keepratio)\n",
    "    with tf.variable_scope(\"FC_2\"):\n",
    "        # Fc2\n",
    "        _out = tf.add(tf.matmul(_fc_dr1, _w['wd2']), _b['bd2'])\n",
    "    # Return everything\n",
    "    out = {\n",
    "        'input_r': _input_r, 'conv1': _conv1, 'pool1': _pool1, 'pool1_dr1': _pool_dr1,\n",
    "        'conv2': _conv2, 'pool2': _pool2, 'pool_dr2': _pool_dr2, 'dense1': _dense1,\n",
    "        'fc1': _fc1, 'fc_dr1': _fc_dr1, 'out': _out }\n",
    "    return out\n",
    "\n",
    "print (\"Network ready\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Define functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Functions ready\n"
     ]
    }
   ],
   "source": [
    "# tf Graph input\n",
    "x = tf.placeholder(tf.float32, [None, n_input], name=\"CNN_INPUT_x\")\n",
    "y = tf.placeholder(tf.float32, [None, n_output], name=\"CNN_TARGET_y\")\n",
    "keepratio = tf.placeholder(tf.float32, name=\"CNN_DROPOUT_keepratio\")\n",
    "\n",
    "# Functions! \n",
    "pred = conv_basic(x, weights, biases, keepratio)['out']\n",
    "cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))\n",
    "optm = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)\n",
    "corr = tf.equal(tf.argmax(pred,1), tf.argmax(y,1)) # Count corrects\n",
    "accr = tf.reduce_mean(tf.cast(corr, tf.float32)) # Accuracy\n",
    "init = tf.initialize_all_variables()\n",
    "print (\"Functions ready\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Summary "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Summary ready\n"
     ]
    }
   ],
   "source": [
    "# Do some optimizations\n",
    "sess = tf.Session()\n",
    "sess.run(init)\n",
    "\n",
    "# Summary writer\n",
    "tf.scalar_summary('cross entropy', cost)\n",
    "tf.scalar_summary('accuracy', accr)\n",
    "merged = tf.merge_all_summaries()\n",
    "summary_writer = tf.train.SummaryWriter('/tmp/tf_logs/cnn_mnist'\n",
    "                                        , graph=sess.graph)\n",
    "print (\"Summary ready\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Start!\n",
      "Epoch: 000/005 cost: 0.352900247\n",
      " Training accuracy: 0.990\n",
      " Test accuracy: 0.981\n",
      "Epoch: 001/005 cost: 0.047190106\n",
      " Training accuracy: 0.980\n",
      " Test accuracy: 0.988\n",
      "Epoch: 002/005 cost: 0.031958400\n",
      " Training accuracy: 1.000\n",
      " Test accuracy: 0.990\n",
      "Epoch: 003/005 cost: 0.022927662\n",
      " Training accuracy: 1.000\n",
      " Test accuracy: 0.990\n",
      "Epoch: 004/005 cost: 0.018374201\n",
      " Training accuracy: 0.990\n",
      " Test accuracy: 0.991\n",
      "Optimization Finished.\n"
     ]
    }
   ],
   "source": [
    "print (\"Start!\")\n",
    "for epoch in range(training_epochs):\n",
    "    avg_cost = 0.\n",
    "    total_batch = int(mnist.train.num_examples/batch_size)\n",
    "    # Loop over all batches\n",
    "    for i in range(total_batch):\n",
    "        batch_xs, batch_ys = mnist.train.next_batch(batch_size)\n",
    "        # Fit training using batch data\n",
    "        summary, _ = sess.run([merged, optm]\n",
    "                        , feed_dict={x: batch_xs, y: batch_ys, keepratio:0.7})\n",
    "        # Compute average loss\n",
    "        avg_cost += sess.run(cost\n",
    "                , feed_dict={x: batch_xs, y: batch_ys, keepratio:1.})/total_batch\n",
    "        # Add summary\n",
    "        summary_writer.add_summary(summary, epoch*total_batch+i)\n",
    "    # Display logs per epoch step\n",
    "    if epoch % display_step == 0: \n",
    "        print (\"Epoch: %03d/%03d cost: %.9f\" % (epoch, training_epochs, avg_cost))\n",
    "        train_acc = sess.run(accr, feed_dict={x: batch_xs, y: batch_ys, keepratio:1.})\n",
    "        print (\" Training accuracy: %.3f\" % (train_acc))\n",
    "        test_acc = sess.run(accr, feed_dict={x: testimg, y: testlabel, keepratio:1.})\n",
    "        print (\" Test accuracy: %.3f\" % (test_acc))\n",
    "\n",
    "print (\"Optimization Finished.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Run the command line\n",
    "##### tensorboard --logdir=/tmp/tf_logs/cnn_mnist\n",
    "### Open http://localhost:6006/ into your web browser"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/tsboard/cnn_mnist.png\">"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
